{"componentChunkName":"component---src-templates-blog-post-js","path":"/algorithm/quick-sort/","result":{"data":{"site":{"siteMetadata":{"title":"Tory","author":"[Tory]","siteUrl":"https://gatsby-starter-bee.netlify.com","comment":{"disqusShortName":"","utterances":"JaeYeopHan/gatsby-starter-bee"},"sponsor":{"buyMeACoffeeId":"jbee"}}},"markdownRemark":{"id":"5b3610e7-05a4-5f39-b05a-ce966eb9b47e","excerpt":"Jump to Quick Sort 🚴 1. About Quick Sort 퀵 정렬은 분할1과 정복2을(Divide and conquer) 적극적으로 활용한 정렬 알고리즘이다. 퀵 정렬은 PIVOT이라는 기준값이 존재한다. 이 PIVOT을 기준으로 작은 값의 범위, 큰 값의 범위로 나누는 분할&정복 과정을 반복하는 알고리즘이다. 2. Code case1: 리스트의 중앙을 pivot으로 선택. 왼쪽 끝에서 오른쪽으로 리스트를 조회하며 발견된 PIVOT…","html":"<h1 id=\"jump-to-quick-sort-\" style=\"position:relative;\"><a href=\"#jump-to-quick-sort-\" aria-label=\"jump to quick sort  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Jump to Quick Sort 🚴</h1>\n<h2 id=\"1-about-quick-sort\" style=\"position:relative;\"><a href=\"#1-about-quick-sort\" aria-label=\"1 about quick sort permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. About Quick Sort</h2>\n<p>퀵 정렬은 분할[1]과 정복[2]을(Divide and conquer) 적극적으로 활용한 정렬 알고리즘이다.</p>\n<p>퀵 정렬은 PIVOT이라는 기준값이 존재한다. 이 PIVOT을 기준으로 작은 값의 범위, 큰 값의 범위로 나누는 분할&#x26;정복 과정을 반복하는 알고리즘이다.</p>\n<div style=\"text-align:center\"><img src=\"/d4e5d0a778dba725091d8317e6bac939/Sorting_quicksort_anim.gif\" alt=\"this slowpoke moves\"><div></div></div>\n<h2 id=\"2-code\" style=\"position:relative;\"><a href=\"#2-code\" aria-label=\"2 code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Code</h2>\n<p>case1:</p>\n<ol>\n<li>리스트의 중앙을 pivot으로 선택.</li>\n<li>왼쪽 끝에서 오른쪽으로 리스트를 조회하며 발견된 PIVOT 보다 큰 값과 오른쪽 끝에서 왼쪽으로 조회하며 발견된 PIVOT보다 작은 값을 SWAP.</li>\n<li>두 지점이 교차할 때 까지 1번과 2번 과정을 반복.</li>\n<li>교차 지점을 기준으로 왼쪽 리스트와 오른쪽 리스트에 대해 1번부터 3번까지 반복.</li>\n</ol>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">quick_sort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">def</span> <span class=\"token function\">sort</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> right <span class=\"token operator\">&lt;=</span> left<span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">return</span>\n        mid <span class=\"token operator\">=</span> partition<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span>\n        sort<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> mid <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n        sort<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> mid<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">def</span> <span class=\"token function\">partition</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'begin'</span><span class=\"token punctuation\">,</span>arr<span class=\"token punctuation\">)</span>\n        pivot <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>left <span class=\"token operator\">+</span> right<span class=\"token punctuation\">)</span> <span class=\"token operator\">//</span> <span class=\"token number\">2</span>\n        <span class=\"token keyword\">while</span> left <span class=\"token operator\">&lt;=</span> right<span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">while</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>pivot<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>\n                <span class=\"token comment\"># pivot 보다 큰 값을 가진 인덱스를 찾는다.</span>\n                left <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n            <span class=\"token keyword\">while</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>pivot<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>\n                <span class=\"token comment\"># pivot 보다 작은 값을 가진 인덱스를 찾는다.</span>\n                right <span class=\"token operator\">-=</span> <span class=\"token number\">1</span>\n            <span class=\"token keyword\">if</span> left <span class=\"token operator\">&lt;=</span> right<span class=\"token punctuation\">:</span>\n                arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span>\n                right <span class=\"token operator\">-=</span> <span class=\"token number\">1</span>\n                left <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n            <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'ing'</span><span class=\"token punctuation\">,</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> left\n    sort<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\nx <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span>\nquick_sort<span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span></code></pre></div>\n<h3 id=\"21-디테일-조건\" style=\"position:relative;\"><a href=\"#21-%EB%94%94%ED%85%8C%EC%9D%BC-%EC%A1%B0%EA%B1%B4\" aria-label=\"21 디테일 조건 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2.1. 디테일 조건</h3>\n<p>퀵정렬 처럼 구현 과정에서 while로 반복문을 처리하는 경우와 재귀함수를 실행하는 경우 종료조건을 매우 엄밀하게 설정해 주어야 한다.</p>\n<ol>\n<li>재귀함수의 종료조건: 처음 리스트가 분할되며 left와 right가 같아지는 순간이 더이상 분할될 수 없는 종료조건이라고 생각했다. 하지만 right가 left보다 작아지는 순간이 발생한다.</li>\n</ol>\n<p><strong>예시</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token triple-quoted-string string\">'''in quick_sort function'''</span>\nmid <span class=\"token operator\">=</span> partition<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span> <span class=\"token comment\"># left = 0, right = 1</span>\nsort<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> mid <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token comment\"># left = 1, mid = 0</span>\nsort<span class=\"token punctuation\">(</span>arr<span class=\"token punctuation\">,</span> mid<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span>\n\n<span class=\"token triple-quoted-string string\">'''in partition method'''</span>\n<span class=\"token keyword\">if</span> left <span class=\"token operator\">&lt;=</span> right<span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>left<span class=\"token punctuation\">,</span>right<span class=\"token punctuation\">)</span>\n    arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span>\n    right <span class=\"token operator\">-=</span> <span class=\"token number\">1</span>\n    left <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n<span class=\"token keyword\">return</span> right <span class=\"token comment\"># 0 => mid가 됨</span></code></pre></div>\n<ul>\n<li>left와 right가 같은 경우는 이미 return을 시키고 있기 때문에 제외한다.</li>\n<li>left가 0이고 right 가 1인 경우를 살펴보자.\n이부분에서 정렬이 되어있는 경우라면 right가 왼쪽으로 이동해서 0의 위치에 있게 된다. 그리고 left와 right가 같기 때문에 조건문에서 재자리 스왑이 일어나는 동시에 left는 1 right는 -1 이 된다. 따라서 <strong>mid는 기존 left의 -1</strong> 이 된 상태로 반환된다. 즉 left는 0 mid 는 -1이 되기 때문에 종료 조건문을 right &#x3C;= left로 수정해 주어야 한다.</li>\n<li>하지만 만약 return left를 해준다면,\n<strong>mid는 기존 left보다 1 커진 값</strong>을 반환한다.\n따라서 mid가 1가 되고 다음 퀵정렬의 왼쪽 범위는 <code class=\"language-text\">sort(arr, left, mid - 1)</code>로 left(0), mid(1) - 1 이기 때문에 == 조건에서 탈출된다. 또한 다음 퀵정렬의 오른쪽 범위는\n<code class=\"language-text\">sort(arr, mid, right)</code>로 mid(1) right(1)이기 때문에 == 조건에서 탈출하게 된다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">while</span> left <span class=\"token operator\">&lt;=</span> right<span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">while</span> arr<span class=\"token punctuation\">[</span>left<span class=\"token punctuation\">]</span> <span class=\"token operator\">&lt;</span> arr<span class=\"token punctuation\">[</span>pivot<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span> <span class=\"token comment\"># pivot 보다 큰 값을 가진 인덱스를 찾는다.</span>\n        left <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n    <span class=\"token keyword\">while</span> arr<span class=\"token punctuation\">[</span>right<span class=\"token punctuation\">]</span> <span class=\"token operator\">></span> arr<span class=\"token punctuation\">[</span>pivot<span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span> <span class=\"token comment\"># pivot 보다 작은 값을 가진 인덱스를 찾는다.</span>\n        right <span class=\"token operator\">-=</span> <span class=\"token number\">1</span></code></pre></div>\n<ul>\n<li>만약 <code class=\"language-text\">if left &lt;= right</code>를 <code class=\"language-text\">if left &lt; right</code>로 수정해주면 어떤 일이 발생할까? left와 right가 같아지는 순간 while 문을 벗어날 수 없게 된다. => left &#x3C;= right 조건에서도 반복되기 때문에.</li>\n<li>이 때 위의 조건을 탈출하기 위해 <code class=\"language-text\">while left &lt; right</code>로 바꿔주면, left가 0 right가 1처럼 1 인덱스가 차이나고 정렬이 되어있는 경우라면, partition의 안쪽에서는 left와 right가 모두 0이 되는 상황이 발생한다. 이때 mid는 left와 같아은 값을 반환한다. 즉 <code class=\"language-text\">sort(arr, mid, right)</code>는 계속 0과 1을 입력하게 되어 재귀문을 빠져나갈 수 없게 된다.\n=> `sort(arr, mid, right)는 mid가 left와 같아지는 상황이 발생하면 무조건 재귀에 빠지게 된다.</li>\n</ul>\n<hr>\n<p><strong>주석</strong>:</p>\n<p>[1] 분할: 커다란 문제를 작은 문제로 나누어 해결하는 과정</p>\n<p>[2] 정복: 분할된 부분을 특정 기준에 맞게 만들어 가는 과정</p>\n<p><strong>참조</strong>:</p>\n<ol>\n<li><a href=\"https://en.wikipedia.org/wiki/Quicksort#:~:text=Quicksort%20is%20a%20divide%2Dand,sometimes%20called%20partition%2Dexchange%20sort.\">quicksort-wikipedia</a></li>\n</ol>","frontmatter":{"title":"Quick Sort","date":"April 03, 2021"}}},"pageContext":{"slug":"/algorithm/quick-sort/","previous":{"fields":{"slug":"/development/quick_start/"},"frontmatter":{"title":"Quick Start","category":"development","draft":false}},"next":{"fields":{"slug":"/algorithm/insertion-sort/"},"frontmatter":{"title":"Insertion Sort","category":"algorithm","draft":false}}}},"staticQueryHashes":["3128451518","521680639"]}